//
//  Listing1.m
//  SchmoozingExamples
//
//  Created by garrison on Fri Apr 20 2001.
//  Copyright (c) 2001 Standard Orbit Software, LLC. All rights reserved.
//
//  Permission is granted to use this code for any purpose, at your own risk.
//  No warranties are expressed or implied.

#import <Foundation/Foundation.h>
#import <OmniNetworking/OmniNetworking.h>

int main (int argc, const char * argv[])
{
    // TCP Client Using OmniNetworking
    
    NSAutoreleasePool *mainPool;
    ONHost *serverHost;
    ONTCPSocket *connectionSocket;
    NSString *serverHostname = @"www.machack.com";
    unsigned short serverPort = 80;
    
    mainPool = [[NSAutoreleasePool alloc] init];
  
    NS_DURING {
        serverHost = [ONHost hostForHostname:serverHostname];
        // Step 1. Get the Internet address of the server.
    }
    NS_HANDLER {
        // hostForHostname: can throw any of four exceptions
        //
        // ONHostNotFoundExceptionName
        // - covers three error conditions from the resolver library: 
        // 	a) the name doesn't exist in the host name resolution database, 
        // 	b) a temporary error from which recovery might possible,
        // 	c) a unrecoverable error was returned by the resolver library.
        //
        // ONHostNameLookupErrorExceptionName
        // - The resolver library returned some unspecified error.
        //
        // ONHostHasNoAddressExceptionName
        // - The host name was found but the database has no Internet address 
        // associated with it.
        //
        // ONGetHostByNameNotFoundExceptionName
        // - The ONGetHostByName tool on which OmniNetworking relies for thread-safe
        // name lookups cannot be found, indicating bad build or installation of the
        // framework.
        
 //       NSLog(@"hostForHostname: raised %@ (%@)", [localException name], localException );
        exit(1);
    }
    NS_ENDHANDLER
    
 
  
    NS_DURING {
        connectionSocket = [ONTCPSocket tcpSocket];
        // Step 2. Allocate a socket.
        
        [connectionSocket setLocalPortNumber];
        // Step 3. Configure the socket to use an arbitrary local port number.
        
        [connectionSocket connectToHost:serverHost port:serverPort];
        // Step 4. Connect to the server.
    }
    NS_HANDLER {
        // tcpSocket: throws ONInternetSocketConnectFailedExceptionName
        // if the underlying called to socket() returns a -1.
        
        // setLocalPortNumber: throws ONInternetSocketBindFailedExceptionName
        // if the socket cannot be bound to a local port number
        
        // connectToHost: throws 
        // - ONInternetSocketConnectFailedExceptionName if the host argument is bad
        // - ONInternetSocketConnectTemporarilyFailedExceptionName if no connection
        // could be made using any of host's known Internet addresses.
        
     //  NSLog(@"tcpSocket: raised %@ (%@)", [localException name], localException );
        exit(1);
    }
    NS_ENDHANDLER
    
    
    // Step 5. Communicate with server using some application protocol.  In this example,
    // I'll use HTTP to request the root page from the MacHack web site.  I'll use
    // ONTCPSocket's NSString-based I/O methods
    
    NS_DURING {
        NSString *httpRequest = @"GET / HTTP 1.0\r\n\r\n";
        NSMutableString *httpReply = [NSMutableString string];
        NSString *chunk;
        
        [connectionSocket writeString: httpRequest];
        // Send the HTTP request to the server.
                
        while ( chunk = [connectionSocket readString] )
                [httpReply appendString: chunk];
        // Read the response.  readString: will read up to 2048 bytes from the socket 
        // at a time, unless the read buffer size has been changed.  TCP is a byte stream
        // protocol, so you'll need to read until there are no more bytes on the socket
        // to ensure that you have a complete message.  readString: returns nil when there
        // are no more bytes on the socket.  The first call to readString: will block 
        // the program until there are bytes available to read.  Use ONTCPSocket's
        // waitForInputWithTimeout: method to set up a timer on the first read to keep
        // your application from locking up on a slow or unresponsive connection.
        // "www.hp.com" is a good site to use for slow response testing.
        
        NSLog(@"%@", httpReply);
    }
    NS_HANDLER {
        // Either readString: and writeString: can throw...
        // ONInternetSocketUserAbortExceptionName, if the connection is
        // aborted (via abortSocket:), or
        // ONInternetSocketWouldBlockExceptionName, if the socket is in non-blocking
        // mode and a read or write would have caused the socket to block.
        //
        // readString: (and the other read methods) throws
        // ONInternetSocketReadFailedExceptionName if the read fails.
        //
        // writeString: (and the other write methods) throws
        // ONInternetSocketWriteFailedExceptionName if the write fails.
        
       // NSLog(@"Socket I/O raised %@ (%@)", [localException name], localException);
        exit(1);        
    }
    NS_ENDHANDLER
    
    [mainPool release];
    // Step 6. The connection socket is closed when the pool is released.
    
    return(0);
    exit(0);
}